"""互动控制器"""
import logging
from typing import Dict, Any, List, Optional
from sqlalchemy.orm import Session
from sqlalchemy import desc
from app.models.like import Like
from app.models.favorite import Favorite
from app.models.comment import Comment
from app.models.video import Video
from app.models.user import User
from app.schemas.interaction import CommentRequest
from app.utils.redis_util import redis_util

logger = logging.getLogger(__name__)


class InteractionController:
    """互动控制器类"""
    
    @staticmethod
    def toggle_like(db: Session, user_id: int, video_id: int) -> Dict[str, Any]:
        """切换视频点赞状态"""
        # 检查视频是否存在
        video = db.query(Video).filter(Video.id == video_id).first()
        if not video:
            raise ValueError("视频不存在")
        
        # 检查是否已经点赞
        existing_like = db.query(Like).filter(
            Like.user_id == user_id,
            Like.video_id == video_id
        ).first()
        
        if existing_like:
            # 取消点赞
            db.delete(existing_like)
            # 更新视频点赞数
            video.like_count = max(0, video.like_count - 1)
            db.commit()
            
            # 更新Redis缓存
            redis_util.delete_cache(f"video:detail:{video_id}")
            redis_util.remove_from_liked_set(user_id, video_id)
            
            return {
                "success": True,
                "liked": False,
                "like_count": video.like_count
            }
        else:
            # 添加点赞
            new_like = Like(
                user_id=user_id,
                video_id=video_id
            )
            db.add(new_like)
            # 更新视频点赞数
            video.like_count += 1
            db.commit()
            
            # 更新Redis缓存
            redis_util.delete_cache(f"video:detail:{video_id}")
            redis_util.add_to_liked_set(user_id, video_id)
            
            return {
                "success": True,
                "liked": True,
                "like_count": video.like_count
            }
    
    @staticmethod
    def toggle_favorite(db: Session, user_id: int, video_id: int) -> Dict[str, Any]:
        """切换视频收藏状态"""
        # 检查视频是否存在
        video = db.query(Video).filter(Video.id == video_id).first()
        if not video:
            raise ValueError("视频不存在")
        
        # 检查是否已经收藏
        existing_favorite = db.query(Favorite).filter(
            Favorite.user_id == user_id,
            Favorite.video_id == video_id
        ).first()
        
        if existing_favorite:
            # 取消收藏
            db.delete(existing_favorite)
            # 更新视频收藏数
            video.collect_count = max(0, video.collect_count - 1)
            db.commit()
            
            # 更新Redis缓存
            redis_util.delete_cache(f"video:detail:{video_id}")
            redis_util.remove_from_favorite_set(user_id, video_id)
            
            return {
                "success": True,
                "favorited": False,
                "collect_count": video.collect_count
            }
        else:
            # 添加收藏
            new_favorite = Favorite(
                user_id=user_id,
                video_id=video_id
            )
            db.add(new_favorite)
            # 更新视频收藏数
            video.collect_count += 1
            db.commit()
            
            # 更新Redis缓存
            redis_util.delete_cache(f"video:detail:{video_id}")
            redis_util.add_to_favorite_set(user_id, video_id)
            
            return {
                "success": True,
                "favorited": True,
                "collect_count": video.collect_count
            }
    
    @staticmethod
    def add_comment(db: Session, user_id: int, video_id: int, comment_data: CommentRequest) -> Comment:
        """添加视频评论"""
        # 检查视频是否存在
        video = db.query(Video).filter(Video.id == video_id).first()
        if not video:
            raise ValueError("视频不存在")
        
        # 检查父评论是否存在（如果有）
        if comment_data.parent_id:
            parent_comment = db.query(Comment).filter(
                Comment.id == comment_data.parent_id,
                Comment.video_id == video_id
            ).first()
            if not parent_comment:
                raise ValueError("父评论不存在")
        
        # 创建新评论
        new_comment = Comment(
            user_id=user_id,
            video_id=video_id,
            content=comment_data.content,
            parent_id=comment_data.parent_id
        )
        
        db.add(new_comment)
        # 更新视频评论数
        video.comment_count += 1
        db.commit()
        db.refresh(new_comment)
        
        # 更新Redis缓存
        redis_util.delete_cache(f"video:detail:{video_id}")
        
        return new_comment
    
    @staticmethod
    def get_video_comments(db: Session, video_id: int, page: int = 1, pageSize: int = 20) -> Dict[str, Any]:
        """获取视频评论列表"""
        # 验证参数
        if video_id <= 0:
            raise ValueError("视频ID无效")
        if page < 1:
            page = 1
        if pageSize < 1 or pageSize > 50:
            pageSize = 20
        
        # 尝试从缓存获取
        cache_key = f"video:comments:{video_id}:page:{page}:size:{pageSize}"
        cached_data = redis_util.get_cache(cache_key)
        if cached_data:
            return cached_data
        
        # 缓存未命中，查询数据库
        # 只获取一级评论，子评论可以通过其他接口加载
        query = db.query(Comment, User.username, User.nickname, User.avatar).join(
            User, Comment.user_id == User.id
        ).filter(
            Comment.video_id == video_id,
            Comment.parent_id.is_(None)  # 只获取一级评论
        )
        
        total = query.count()
        offset = (page - 1) * pageSize
        limit = pageSize
        
        comments_with_user = query.order_by(desc(Comment.created_at)).offset(offset).limit(limit).all()
        
        # 转换为响应格式
        comments_data = []
        for comment, username, nickname, avatar in comments_with_user:
            # 获取该评论的子评论数量
            sub_comment_count = db.query(Comment).filter(
                Comment.parent_id == comment.id
            ).count()
            
            comment_dict = {
                "id": comment.id,
                "user_id": comment.user_id,
                "username": username,
                "nickname": nickname,
                "avatar": avatar,
                "content": comment.content,
                "parent_id": comment.parent_id,
                "sub_comment_count": sub_comment_count,
                "created_at": comment.created_at.isoformat() if comment.created_at else None
            }
            comments_data.append(comment_dict)
        
        total_pages = (total + pageSize - 1) // pageSize
        result = {
            "list": comments_data,
            "total": total,
            "page": page,
            "pageSize": pageSize,
            "totalPages": total_pages,
            "fromCache": False
        }
        
        # 设置缓存（5分钟）
        redis_util.set_cache(cache_key, result, 300)
        
        return result
    
    @staticmethod
    def get_comment_replies(db: Session, comment_id: int, page: int = 1, pageSize: int = 20) -> Dict[str, Any]:
        """获取评论的回复列表"""
        # 验证参数
        if comment_id <= 0:
            raise ValueError("评论ID无效")
        if page < 1:
            page = 1
        if pageSize < 1 or pageSize > 50:
            pageSize = 20
        
        # 尝试从缓存获取
        cache_key = f"comment:replies:{comment_id}:page:{page}:size:{pageSize}"
        cached_data = redis_util.get_cache(cache_key)
        if cached_data:
            return cached_data
        
        # 缓存未命中，查询数据库
        # 检查父评论是否存在
        parent_comment = db.query(Comment).filter(Comment.id == comment_id).first()
        if not parent_comment:
            raise ValueError("父评论不存在")
        
        query = db.query(Comment, User.username, User.nickname, User.avatar).join(
            User, Comment.user_id == User.id
        ).filter(
            Comment.parent_id == comment_id
        )
        
        total = query.count()
        offset = (page - 1) * pageSize
        limit = pageSize
        
        replies_with_user = query.order_by(Comment.created_at).offset(offset).limit(limit).all()
        
        # 转换为响应格式
        replies_data = []
        for comment, username, nickname, avatar in replies_with_user:
            reply_dict = {
                "id": comment.id,
                "user_id": comment.user_id,
                "username": username,
                "nickname": nickname,
                "avatar": avatar,
                "content": comment.content,
                "parent_id": comment.parent_id,
                "created_at": comment.created_at.isoformat() if comment.created_at else None
            }
            replies_data.append(reply_dict)
        
        total_pages = (total + pageSize - 1) // pageSize
        result = {
            "list": replies_data,
            "total": total,
            "page": page,
            "pageSize": pageSize,
            "totalPages": total_pages,
            "fromCache": False
        }
        
        # 设置缓存（5分钟）
        redis_util.set_cache(cache_key, result, 300)
        
        return result
    
    @staticmethod
    def delete_comment(db: Session, comment_id: int, user_id: int) -> bool:
        """删除评论（仅评论作者可删除）"""
        # 查找评论
        comment = db.query(Comment).filter(
            Comment.id == comment_id,
            Comment.user_id == user_id
        ).first()
        
        if not comment:
            raise ValueError("评论不存在或无权删除")
        
        # 获取视频ID用于更新评论数
        video_id = comment.video_id
        
        # 开始事务
        try:
            # 计算要删除的评论总数（包括子评论）
            def count_comments_and_delete(comment_id):
                # 获取子评论
                sub_comments = db.query(Comment).filter(Comment.parent_id == comment_id).all()
                count = 1  # 当前评论
                
                for sub_comment in sub_comments:
                    count += count_comments_and_delete(sub_comment.id)
                
                # 删除当前评论
                db.delete(comment)
                return count
            
            deleted_count = count_comments_and_delete(comment_id)
            
            # 更新视频评论数
            video = db.query(Video).filter(Video.id == video_id).first()
            if video:
                video.comment_count = max(0, video.comment_count - deleted_count)
            
            db.commit()
            
            # 更新Redis缓存
            redis_util.delete_cache(f"video:detail:{video_id}")
            redis_util.delete_cache_pattern(f"video:comments:{video_id}:*")
            redis_util.delete_cache_pattern(f"comment:replies:{comment_id}:*")
            
            return True
        except Exception as e:
            db.rollback()
            logger.error(f"删除评论失败: {e}")
            raise


# 创建全局互动控制器实例
interaction_controller = InteractionController()
